﻿using JwtConstants = MicroCloud.JwtConstants;

namespace MicroCloud
{
    #region "<see cref="UserManager{TUser}"/> 辅助扩展"
    /// <summary>
    /// <see cref="UserManager{TUser}"/> 辅助扩展
    /// </summary>
    public static class UserManagerExtensions
    {
        #region "扩展方法"
        #region "异步获取RefreshToken集合"
        /// <summary>
        /// 异步获取RefreshToken集合
        /// </summary>
        /// <typeparam name="TUser"></typeparam>
        /// <param name="userManager"></param>
        /// <param name="serviceProvider"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public static async Task<RefreshToken[]> GetRefreshTokensAsync<TUser>(this UserManager<TUser> userManager, IServiceProvider serviceProvider, string userId)
            where TUser : class
        {
            TUser user = await userManager.FindByIdAsync(userId);
            if (user == null)
            {
                throw new Exception(I18N.T("用户 {0} 不存在", userId));
            }
            return await user.GetRefreshTokensAsync(serviceProvider);
        }
        #endregion
        #region "异步获取RefreshToken集合"
        /// <summary>
        /// 异步获取RefreshToken集合
        /// </summary>
        /// <typeparam name="TUser"></typeparam>
        /// <param name="user"></param>
        /// <param name="serviceProvider"></param>
        /// <returns></returns>
        public static async Task<RefreshToken[]> GetRefreshTokensAsync<TUser>(this TUser user, IServiceProvider serviceProvider)
            where TUser : class
        {
            if (serviceProvider.GetService<IUserStore<TUser>>() is not IMicroCloudUserAuthenticationTokenStore<TUser> store)
            {
                return Array.Empty<RefreshToken>();
            }
            //const string loginProvider = "JwtBearer";
            string[] jsons = await store.GetTokensAsync(user, JwtConstants.Provider, CancellationToken.None);
            if (jsons.Length == 0)
            {
                return Array.Empty<RefreshToken>();
            }
            RefreshToken[] tokens = jsons.Select(m => m.FromJsonString<RefreshToken>()).ToArray();
            return tokens;
        }
        #endregion

        #region "异步获取RefreshToken"
        /// <summary>
        /// 异步获取RefreshToken
        /// </summary>
        /// <typeparam name="TUser"></typeparam>
        /// <param name="userManager"></param>
        /// <param name="userId"></param>
        /// <param name="clientId"></param>
        /// <returns></returns>
        public static async Task<RefreshToken> GetRefreshTokenAsync<TUser>(this UserManager<TUser> userManager, string userId, string clientId)
            where TUser : class
        {
            TUser user = await userManager.FindByIdAsync(userId);
            if (user == null)
            {
                throw new Exception(I18N.T("用户 {0} 不存在", userId));
            }
            return await userManager.GetRefreshTokenAsync(user, clientId);
        }
        #endregion
        #region "异步获取RefreshToken"
        /// <summary>
        /// 异步获取RefreshToken
        /// </summary>
        /// <typeparam name="TUser"></typeparam>
        /// <param name="userManager"></param>
        /// <param name="user"></param>
        /// <param name="clientId"></param>
        /// <returns></returns>
        public static async Task<RefreshToken> GetRefreshTokenAsync<TUser>(this UserManager<TUser> userManager, TUser user, string clientId)
            where TUser : class
        {
            //const string loginProvider = "JwtBearer";
            //string tokenName = $"RefreshToken_{clientId}";
            string tokenName = GetTokenName(clientId);
            string json = await userManager.GetAuthenticationTokenAsync(user, JwtConstants.Provider, tokenName);
            if (string.IsNullOrEmpty(json))
            {
                return null;
            }
            return json.FromJsonString<RefreshToken>();
        }
        #endregion

        #region "异步设置RefreshToken"
        /// <summary>
        /// 异步设置RefreshToken
        /// </summary>
        /// <typeparam name="TUser"></typeparam>
        /// <param name="userManager"></param>
        /// <param name="userId"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public static async Task<IdentityResult> SetRefreshTokenAsync<TUser>(this UserManager<TUser> userManager, string userId, RefreshToken token)
            where TUser : class
        {
            TUser user = await userManager.FindByIdAsync(userId);
            if (user == null)
            {
                return new IdentityResult().Failed(I18N.T("用户 {0} 不存在", userId));
            }
            return await userManager.SetRefreshTokenAsync(user, token);
        }
        #endregion
        #region "异步设置RefreshToken"
        /// <summary>
        /// 异步设置RefreshToken
        /// </summary>
        /// <typeparam name="TUser"></typeparam>
        /// <param name="userManager"></param>
        /// <param name="user"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public static Task<IdentityResult> SetRefreshTokenAsync<TUser>(this UserManager<TUser> userManager, TUser user, RefreshToken token)
            where TUser : class
        {
            //const string loginProvider = "JwtBearer";
            //string tokenName = $"RefreshToken_{token.ClientId}";
            string tokenName = GetTokenName(token.ClientId);
            string json = token.ToJsonString();
            return userManager.SetAuthenticationTokenAsync(user, JwtConstants.Provider, tokenName, json);
        }
        #endregion

        #region "异步移除RefreshToken"
        /// <summary>
        /// 异步移除RefreshToken
        /// </summary>
        /// <typeparam name="TUser"></typeparam>
        /// <param name="userManager"></param>
        /// <param name="userId"></param>
        /// <param name="clientId"></param>
        /// <returns></returns>
        public static async Task<IdentityResult> RemoveRefreshTokenAsync<TUser>(this UserManager<TUser> userManager, string userId, string clientId)
            where TUser : class
        {
            TUser user = await userManager.FindByIdAsync(userId);
            if (user == null)
            {
                return new IdentityResult().Failed(I18N.T("用户 {0} 不存在", userId));
            }
            return await RemoveRefreshTokenAsync(userManager, user, clientId);
        }
        #endregion
        #region "异步移除RefreshToken"
        /// <summary>
        /// 异步移除RefreshToken
        /// </summary>
        /// <typeparam name="TUser"></typeparam>
        /// <param name="userManager"></param>
        /// <param name="user"></param>
        /// <param name="clientId"></param>
        /// <returns></returns>
        public static Task<IdentityResult> RemoveRefreshTokenAsync<TUser>(this UserManager<TUser> userManager, TUser user, string clientId)
            where TUser : class
        {
            //const string loginProvider = "JwtBearer";
            //string tokenName = $"RefreshToken_{clientId}";
            string tokenName = GetTokenName(clientId);
            return userManager.RemoveAuthenticationTokenAsync(user, JwtConstants.Provider, tokenName);
        }
        #endregion

        #endregion

        #region "私有方法"
        #region "获取令牌名称"
        /// <summary>
        /// 获取令牌名称
        /// </summary>
        /// <param name="clientId">客户端编号</param>
        /// <returns></returns>
        private static string GetTokenName(string clientId)
        {
            Check.NotNullOrEmpty(clientId, nameof(clientId));

            string tokenName = $"{JwtConstants.RefreshTokenNamePrefix}_{clientId}";
            return tokenName;
        }
        #endregion

        #endregion

    }
    #endregion

}
